#include <iostream>
#include <queue>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <string>
#include <thread>
#include <functional>              //单例模式

using namespace std;

class Thread_pool {
public:
	Thread_pool(int numThreads) :is_stop(false) {
		for (int i = 0; i < numThreads; i++) {
			threads.emplace_back([this] {
				while (1) {
					unique_lock<mutex> lock(mux);
					condition.wait(lock, [this] {        //保证任务队列不为空或者线程池的状态为打开
						return !tasks.empty() || is_stop;
						});

					if (is_stop && tasks.empty()) {
						return;
					}
					//娶任务
					function<void()> task(move(tasks.front()));
					tasks.pop();
					lock.unlock();

					task();
					//unique_lock<mutex> unlock(mux);
				}
				});
		}
	}

	~Thread_pool() {
		{
			unique_lock<mutex> lock(mux);
			is_stop = true;
		}  

		condition.notify_all();
		for (auto& t : threads) {
			t.join();
		}
	}

	//添加任务到线程池队列     函数模板--->不仅可以添加函数，还可以添加函数对象、Lambda 表达式等
	template<class F, class... Args>
	void enqueue(F&& f, Args &&...args) {  //右值引用&&    绑定器bind  完美转发forward
		function<void()> task = bind(forward<F>(f), forward<Args>(args)...);

		{
			unique_lock<mutex> lock(mux);
			tasks.emplace(move(task));
		}

		condition.notify_one();

	};

private:
	//线程数组
	vector<thread> threads;
	//任务队列   任务应该为函数
	queue <function<void()>> tasks;
	//互斥锁
	mutex mux;
	//条件变量
	condition_variable condition;
	//线程池开关
	bool is_stop;

};

int main() {

	Thread_pool pool(4);
	for (int i = 0; i < 10; i++) {
		pool.enqueue([i] {
			std::mutex mut;
			std::unique_lock<std::mutex> lock(mut);
			std::cout << "task: " << i << "is runing" << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(1));
			std::cout << "task:" << i << "is done" << std::endl;
			lock.unlock();
			});
	}

	return 0;
}